﻿//==============================================================================
// File: ProgressViewPresentationModel.cs
// Created: 2010-06-07
// Author: Piotr Włodek, Arkadiusz Świerczek
//==============================================================================
// This file is a part of MAMMOTH project.
// Copyright (C) 2010 AGH University of Science and Technology, Krakow.
// https://caribou.iisg.agh.edu.pl/trac/mammoth
//
// Mammoth is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// Mammoth is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with Mammoth. If not, see http://www.gnu.org/licenses/.
//==============================================================================

using System;
using Caliburn.Core.Invocation;
using WpfRcp.Core.Services.Status;
using Microsoft.Practices.Composite.Presentation.Commands;

namespace WpfRcp.Core.Views.Presenters
{
    public class ProgressViewPresentationModel : PresenterBase<IProgressView>
    {
        private ISimpleRcpStatusMonitor m_Monitor;
        
        private bool m_CancelRequested;

        public ProgressViewPresentationModel(IProgressView view)
        {
            CancelCommand = new DelegateCommand<object>(ExecuteCancelCommand, CanExecuteCancelCommand);
            SendToBackgroundCommand = new DelegateCommand<object>(ExecuteSendToBackgroundCommand, CanExecuteSendToBackgroundCommand);

            View = view;
            View.PresentationModel = this;
        }
        
        public DelegateCommand<object> CancelCommand { get; private set; }

        public DelegateCommand<object> SendToBackgroundCommand { get; private set; }

        public ISimpleRcpStatusMonitor Monitor
        {
            get { return m_Monitor; }
            set
            {
                m_Monitor = value;
                OnPropertyChanged<ProgressViewPresentationModel>(t => t.Monitor);

                CancelCommand.RaiseCanExecuteChanged();
                SendToBackgroundCommand.RaiseCanExecuteChanged();
            }
        }

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (disposing && View is IWindowedProgressView)
            {
                Execute.OnUIThread(() => ((IWindowedProgressView) View).Close());
            }
        }

        public bool? ShowDialog()
        {
            if (!Disposed)
            {
                var progressView = View as IWindowedProgressView;
                if (progressView == null)
                    throw new InvalidOperationException("Cannot call ShowDialog() if underlying progress view is not a window.");

                return progressView.ShowDialog();
            }

            return false;
        }

        public void Show()
        {
            if (!Disposed)
            {
                var progressView = View as IWindowedProgressView;
                if (progressView == null)
                    throw new InvalidOperationException("Cannot call Show() if underlying progress view is not a window.");

                progressView.Show();   
            }
        }

        private void ExecuteCancelCommand(object p)
        {
            Monitor.Cancel();
            
            m_CancelRequested = true;

            CancelCommand.RaiseCanExecuteChanged();
        }

        private bool CanExecuteCancelCommand(object p)
        {
            return Monitor != null && Monitor.Cancelable && !m_CancelRequested;
        }

        private void ExecuteSendToBackgroundCommand(object p)
        {
            Monitor.SendToBackground();
        }

        private bool CanExecuteSendToBackgroundCommand(object p)
        {
            return Monitor != null && Monitor.Backgroundable;
        }
    }
}